package com.etc;

import java.io.*;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Arrays;

import org.apache.commons.lang.StringUtils;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FSDataInputStream;
import org.apache.hadoop.fs.FSDataOutputStream;
import org.apache.hadoop.fs.FileStatus;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.LocatedFileStatus;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.fs.RemoteIterator;
import org.apache.hadoop.io.IOUtils;
import org.junit.Before;
import org.junit.Test;

/**
 * @Auther: zhezhe
 * @Date: 2018/10/1610:49
 * @Description:
 */
public class HdfsClient {

//    @Test
//    public void mkdir() throws IOException {

//        Configuration conf = new Configuration();
//        System.setProperty("HADOOP_USER_NAME","root");
//        conf.set("fs.defaultFS","hdfs://192.168.88.100:9000");
//        FileSystem fs = FileSystem.newInstance(conf);
//        fs.mkdirs(new Path("/b"));
//    }
FileSystem fs = null;

    @Before
    public void init() throws URISyntaxException, IOException, InterruptedException {
        Configuration configuration = new Configuration();
        //指定本客户端上传文件到hdfs是需要保存的副本数是2
        configuration.set("dfs,replication", "2");

        //指定本客户端上传文件到hdfs时切块的规格大小：64m
        configuration.set("dfs.blocksize", "64m");

        //构造一个访问指定HDFS系统的客户端对：参数1：HDFS系统的URI    参数2：客户端要指定特别的参数
        //参数3：客户端的身份（指用户名）
        fs = FileSystem.get(new URI("hdfs://192.168.88.100:9000"), configuration, "root");
    }


    /**
     * 从HDFS下载文件到本地磁盘
     */
    @Test
    public void testGet() throws IOException {
        fs.copyToLocalFile(new Path("/b"), new Path("/"));
        fs.close();
    }
    /**
     在hdfs内部移动文件/修改名称
     */
    @Test
    public void testRename() throws IOException {
        fs.rename(new Path("/test1"),new Path("/test2"));
        fs.close();
    }


    /**
     * HDFS中创建文件夹
     */
    @Test
    public void testMkdir() throws IOException {
        fs.mkdirs(new Path("/zhe/1/1.1"));
        fs.close();
    }

    /**
     * 在hdfs中删除文件或者文件夹
     */
    @Test
    public void testRm() throws IOException {
        fs.delete(new Path("/zhe"),true);
        fs.close();
    }

    /**
     * 查询hdfs指定目录下的文件信息
     */
    @Test
    public void testLs() throws IOException {
        RemoteIterator<LocatedFileStatus> iter = fs.listFiles(new Path("/"),true);
        while (iter.hasNext()){
            LocatedFileStatus status = iter.next();
            System.out.println("文件全路径："+status.getPath());
            System.out.println("块大小："+status.getBlockSize());
            System.out.println("文件长度"+status.getLen());
            System.out.println("副本数量"+status.getReplication());
            System.out.println("块信息"+ Arrays.toString(status.getBlockLocations()));
        }
        fs.close();
    }


    /**
     * 查询hdfs指定目录下的文件和文件下信息
     */

    @Test
    public void testLs2() throws IOException {

        FileStatus[] listStatus = fs.listStatus(new Path("/"));
        for (FileStatus status:listStatus){
            System.out.println("文件全路径 :"+ status.getPath());
            System.out.println(status.isDirectory()?"这是文件夹":"这是文件");
            System.out.println("块大小：   "+status.getBlockSize());
            System.out.println("文本长度：   "+status.getLen());
            System.out.println("副本数量：   "+status.getReplication());
            System.out.println("---------------------------------------");
        }
        fs.close();
    }


    /**
     * 本地文件上传至hdfs
     */
    @Test
    public void copyFileToHDFS() throws IOException {
        FileInputStream in  = new FileInputStream(new File("e:\\ "));//读取本地文件
        //指定上传到hdfs的文件路径及上传后的文件名
        OutputStream out =fs.create(new Path("/test3"));
        IOUtils.copyBytes(in,out,4096,true);
        System.out.println("拷贝完成.....");
        fs.close();
    }
}
